package com.scau.phr.common.SearchEngines;

import com.scau.phr.domain.entity.HealthKnowledge;
import com.scau.phr.domain.entity.Newhospital;
import com.scau.phr.domain.mapper.HealthKnowledgeMapper;
import com.scau.phr.domain.mapper.NewhospitalMapper;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.cn.smart.SmartChineseAnalyzer;
import org.apache.lucene.document.*;
import org.apache.lucene.index.*;
import org.apache.lucene.queryparser.classic.ParseException;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.search.*;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.wltea.analyzer.lucene.IKAnalyzer;

import java.io.IOException;
import java.nio.file.Paths;
import java.util.*;


/**
 * 全局搜索引擎
 * Created with IDEA
 * author:scaurb
 * Date:2018/8/13
 * Time:15:29
 **/
@Component
public class MyLucene {

    //索引的保存位置
    public static final String INDEX_PATH = "D:\\lucene";

    @Autowired
    private NewhospitalMapper newhospitalMapper;

    @Autowired
    private HealthKnowledgeMapper healthKnowledgeMapper;

    /**
     * 为Newhospital表创建索引
     * 只需要创建一次
     */
    public void createIndexToNewhospital(){
        try{
            List<Newhospital> list = newhospitalMapper.getAll();
            //传入表明，索引位置为INDEX_PATH + 表名
            IndexWriter writer =  getWriter("Newhospital");
            for(Newhospital item : list){
                //id, name, phone_number, nature, hospital_type, grade, address, address_province, address_city, address_county, address_town, address_detail, introduce, longitude, latitude
                Document doc=new Document();
                doc.add(new StringField("id",item.getId().toString(), Field.Store.YES));
                doc.add(new StringField("name",item.getName(),Field.Store.YES));
                doc.add(new StringField("phone_number",item.getPhoneNumber(),Field.Store.YES));
                doc.add(new StringField("nature",item.getNature(), Field.Store.YES));
                doc.add(new StringField("hospital_type",item.getHospitalType(), Field.Store.YES));
                doc.add(new StringField("grade",item.getGrade(), Field.Store.YES));
                doc.add(new StringField("address",item.getAddress(), Field.Store.YES));

                doc.add(new StringField("address_province",item.getAddressProvince(), Field.Store.YES));
                doc.add(new StringField("address_city",item.getAddressCity(), Field.Store.YES));
                doc.add(new StringField("address_county",item.getAddressCounty(), Field.Store.YES));
                doc.add(new StringField("address_town",item.getAddressTown(), Field.Store.YES));
                doc.add(new StringField("address_detail",item.getAddressDetail(),Field.Store.YES));
                doc.add(new StringField("introduce",item.getIntroduce(),Field.Store.YES));

                doc.add(new StringField("longitude", String.valueOf(item.getLongitude()),Field.Store.YES));
                doc.add(new StringField("latitude", String.valueOf(item.getLatitude()),Field.Store.YES));

                //System.out.println(item.getAddress());
                writer.addDocument(doc);
            }

            writer.close();
        }catch (IOException e){
            System.out.println(e);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 为HealthKnowledge表创建索引
     * 只需创建一次
     */
    public void createIndexToHealthKnowledge(){
        try{
            List<HealthKnowledge> list = healthKnowledgeMapper.getAll();
            IndexWriter writer =  getWriter("HealthKnowledge");
            for(HealthKnowledge item : list){
                Document doc=new Document();
                doc.add(new StringField("id",item.getId().toString(), Field.Store.YES));
                doc.add(new StringField("title",item.getTitle(),Field.Store.YES));
                doc.add(new StringField("author",item.getAuthor(), Field.Store.YES));
                doc.add(new StringField("content",item.getContent(),Field.Store.YES));
                doc.add(new StringField("description",item.getDescription(),Field.Store.YES));
                doc.add(new StringField("image",item.getImage(),Field.Store.YES));

                //System.out.println(item.getAddress());*/
                writer.addDocument(doc);
            }

            writer.close();
        }catch (IOException e){
            System.out.println(e);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private IndexWriter getWriter(String tableName) throws Exception{
        Analyzer analyzer = getAnalyzer();//标准分词器
        String path = INDEX_PATH + "\\" + tableName;
        Directory dir = FSDirectory.open(Paths.get(path, new String[0]));
        IndexWriterConfig conf = new IndexWriterConfig(analyzer);
        conf.setOpenMode(IndexWriterConfig.OpenMode.CREATE_OR_APPEND);
        IndexWriter writer = new IndexWriter(dir, conf);
        return writer;
    }

    /**
     * 获取Analyzer
     * @return
     */
    public Analyzer getAnalyzer(){
        return new IKAnalyzer();
    }

    public ScoreDoc[] searchToNewhospital() throws IOException{
        //获得directory对象
        String path = INDEX_PATH + "\\Newhospital";
        FSDirectory directory = FSDirectory.open(Paths.get(path, new String[0]));
        //获得indexreader对象
        IndexReader reader = DirectoryReader.open(directory);
        //获得查询对象
        IndexSearcher indexSearcher = new IndexSearcher(reader);

        Analyzer analyzer = getAnalyzer();

        //在这里指定要搜索的字段名跟搜索内容（此搜索需要完全匹配）
        Term term = new Term("address_city", "潮州市");

        Query query = new TermQuery(term);

        //进行查询
        TopDocs topDocs = indexSearcher.search(query, 10);
        // 取得结果集
        ScoreDoc[] scoreDocs = topDocs.scoreDocs;

        //System.out.println("SUCCESSFUL");

        System.out.println(scoreDocs.length);
        for (ScoreDoc  scoreDoc  : scoreDocs){
            Document document = indexSearcher.doc(scoreDoc.doc);
            System.out.println("描述中含有容量的item 名字是："+document.getField("address"));
        }

        return scoreDocs;

    }

    /**
     * 根据字段名跟key搜索
     * @param searchField
     * @param searchValue
     * @return
     * @throws IOException
     */
    public List<Newhospital> searchFromNewhospital(String searchField,String searchValue) throws IOException{
        //获得directory对象
        String path = INDEX_PATH + "\\Newhospital";
        FSDirectory directory = FSDirectory.open(Paths.get(path, new String[0]));
        //获得indexreader对象
        IndexReader reader = DirectoryReader.open(directory);
        //获得查询对象
        IndexSearcher indexSearcher = new IndexSearcher(reader);

        Analyzer analyzer = getAnalyzer();

        //在这里指定要搜索的字段名跟搜索内容（此搜索需要完全匹配）
        /*Term term = new Term(searchField, searchValue);
        Query query = new TermQuery(term);*/
        //在这里支持模糊查询
        searchValue = "*" + searchValue + "*";
        Term term = new Term(searchField, searchValue);
        Query query = new WildcardQuery(term);


        //进行查询(n为需要获取的字段数)
        TopDocs topDocs = indexSearcher.search(query, 10);
        // 取得结果集
        ScoreDoc[] scoreDocs = topDocs.scoreDocs;

        //id, name, phone_number, nature, hospital_type, grade, address, address_province, address_city, address_county, address_town, address_detail, introduce, longitude, latitude

        List<Newhospital> list = new ArrayList<Newhospital>();

        //System.out.println("success");
        //System.out.println(searchField + " " + searchValue);
        for (ScoreDoc  scoreDoc  : scoreDocs){
            Document document = indexSearcher.doc(scoreDoc.doc);
            Newhospital hospital = new Newhospital();
            //System.out.println(document.getField("address").stringValue());
            hospital.setId(Long.valueOf(document.getField("id").stringValue()));
            hospital.setName(document.getField("name").stringValue());
            hospital.setPhoneNumber(document.getField("phone_number").stringValue());
            hospital.setNature(document.getField("nature").stringValue());
            hospital.setHospitalType(document.getField("hospital_type").stringValue());
            hospital.setGrade(document.getField("grade").stringValue());
            hospital.setAddress(document.getField("address").stringValue());
            hospital.setAddressProvince(document.getField("address_province").stringValue());
            hospital.setAddressCity(document.getField("address_city").stringValue());
            hospital.setAddressCounty(document.getField("address_county").stringValue());
            hospital.setAddressTown(document.getField("address_town").stringValue());
            hospital.setAddressDetail(document.getField("address_detail").stringValue());
            hospital.setIntroduce(document.getField("introduce").stringValue());
            hospital.setLongitude(Double.valueOf(document.getField("longitude").stringValue()));
            hospital.setLatitude(Double.valueOf(document.getField("latitude").stringValue()));
            list.add(hospital);
        }

        return list;

    }

    public List<HealthKnowledge> searchFromHealthKnowledge(String searchField,String searchValue) throws IOException, ParseException {
        //获得directory对象
        String path = INDEX_PATH + "\\HealthKnowledge";
        FSDirectory directory = FSDirectory.open(Paths.get(path, new String[0]));
        //获得indexreader对象
        IndexReader reader = DirectoryReader.open(directory);
        //获得查询对象
        IndexSearcher indexSearcher = new IndexSearcher(reader);

        Analyzer analyzer = getAnalyzer();

        //在这里支持模糊查询
        searchValue = "*" + searchValue + "*";
        Term term = new Term(searchField, searchValue);
        Query query = new WildcardQuery(term);




        //进行查询(n为需要获取的字段数)
        TopDocs topDocs = indexSearcher.search(query, 10);
        // 取得结果集
        ScoreDoc[] scoreDocs = topDocs.scoreDocs;

        List<HealthKnowledge> list = new ArrayList<>();

        //System.out.println("success");
        //System.out.println(searchField + " " + searchValue);
        for (ScoreDoc  scoreDoc  : scoreDocs){
            Document document = indexSearcher.doc(scoreDoc.doc);
            HealthKnowledge healthKnowledge = new HealthKnowledge();
            //System.out.println(document.getField("address").stringValue());
            healthKnowledge.setId(Long.valueOf(document.getField("id").stringValue()));
            healthKnowledge.setDescription(document.getField("description").stringValue());
            healthKnowledge.setTitle(document.getField("title").stringValue());
            healthKnowledge.setContent(document.getField("content").stringValue());

            list.add(healthKnowledge);
        }

        return list;
    }
}
